<template>
    <BasicModal v-bind="$attrs" @register="registerModal" @ok="handleSubmit" :title="title" :width="1200" destroyOnClose>
        <BasicForm @register="registerForm"/>

        <a-tabs v-model:activeKey="activeKey">
            <a-tab-pane tab="局部规则" key="1" :forceRender="true">
                <JVxeTable
                    ref="vTable1"
                    toolbar
                    rowNumber
                    dragSort
                    rowSelection
                    :maxHeight="580"
                    :dataSource="dataSource1"
                    :columns="columns1">
                    <template #toolbarAfter>
                        <a-alert type="info" showIcon message="局部规则按照你输入的位数有序的校验" style="margin-bottom: 8px;"/>
                    </template>
                </JVxeTable>
            </a-tab-pane>
            <a-tab-pane tab="全局规则" key="2" :forceRender="true">
                <JVxeTable
                    ref="vTable2"
                    toolbar
                    rowNumber
                    dragSort
                    rowSelection
                    :maxHeight="580"
                    :dataSource="dataSource2"
                    :addSetActive="false"
                    :columns="columns2">
                    <template #toolbarAfter>
                        <a-alert type="info" showIcon message="全局规则可校验用户输入的所有字符；全局规则的优先级比局部规则的要高。" style="margin-bottom: 8px;"/>
                    </template>
                </JVxeTable>
            </a-tab-pane>
        </a-tabs>
    </BasicModal>
</template>

<script lang="ts" setup>
    import { BasicModal, useModalInner } from '/@/components/Modal';
    import { BasicForm, useForm } from '/@/components/Form/index';
    import {computed, ref, unref} from "vue";
    import {formSchema} from "./check.rule.data";
    import { saveCheckRule, updateCheckRule } from "./check.rule.api";
    import {JVxeTypes, JVxeColumn, JVxeTableInstance} from '/@/components/jeecg/JVxeTable/types'
    import { pick } from 'lodash-es';

    //设置标题
    const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
    // 声明Emits
    const emit = defineEmits(['register','success']);
    const isUpdate = ref(true);

    //表单配置
    const [registerForm, { resetFields, setFieldsValue, validate, getFieldsValue }] = useForm({
        schemas: formSchema,
        showActionButtonGroup: false
    });

    const activeKey = ref('1')
    let arr1:any[] = []
    let dataSource1 = ref(arr1)
    let arr2:any[] = []
    let dataSource2 = ref(arr2)

    //表单赋值
    const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
        //重置表单
        await resetFields();
        setModalProps({confirmLoading: false});
        isUpdate.value = !!data?.isUpdate;
        activeKey.value = '1'
        dataSource1.value = []
        dataSource2.value = []
        if (unref(isUpdate)) {
            //表单赋值
            await setFieldsValue({
                ...data.record,
            });

            let ruleJson = data.record.ruleJson
            if (ruleJson) {
                let ruleList = JSON.parse(ruleJson)
                // 筛选出全局规则和局部规则
                let global:any[] = [], design:any[] = [], priority = '1'
                ruleList.forEach(rule => {
                    if (rule.digits === '*') {
                        global.push(Object.assign(rule, { priority }))
                    } else {
                        priority = '0'
                        design.push(rule)
                    }
                })
                dataSource1.value = design
                dataSource2.value = global
            }
        }
    });


    const vTable1 = ref<JVxeTableInstance>()
    const vTable2 = ref<JVxeTableInstance>()

    // 验证表格 返回表格数据
    function validateMyTable(tableRef, key){
        return new Promise(((resolve, reject) => {
            tableRef.value!.validateTable().then(errMap => {
                if (errMap) {
                    activeKey.value = key
                    reject()
                } else {
                    const values = tableRef.value!.getTableData()
                    resolve(values);
                }
            })
        }))
    }

    //表单提交事件
    async function handleSubmit() {
        let mainData;
        let globalValues = []
        let designValues = []
        validate().then((formValue)=>{
            mainData = formValue;
            return validateMyTable(vTable1, '1')
        }).then((tableData1:[])=>{
            if(tableData1 && tableData1.length>0){
                designValues = tableData1
            }
            return validateMyTable(vTable2, '2')
        }).then((tableData2:[])=>{
            if(tableData2 && tableData2.length>0){
                globalValues = tableData2
            }
            // 整合两个子表的数据
            let firstGlobal:any[]  = [],  afterGlobal:any[] = []
            for(let i=0;i<globalValues.length;i++){
                let v:any = globalValues[i]
                v.digits = '*'
                if (v.priority === '1') {
                    firstGlobal.push(v)
                } else {
                    afterGlobal.push(v)
                }
            }
            let concatValues = firstGlobal.concat(designValues).concat(afterGlobal)
            let subValues = concatValues.map(i => pick(i, 'digits', 'pattern', 'message'))
            // 生成 formData，用于传入后台
            let ruleJson = JSON.stringify(subValues)
            let formData = Object.assign({}, mainData, { ruleJson })
            saveOrUpdateFormData(formData)
        }).catch(()=>{
            setModalProps({confirmLoading: false});
            console.error("验证未通过!")
        })
    }

    // 表单提交请求
    async function saveOrUpdateFormData(formData) {
        try {
            console.log('表单提交数据', formData)
            setModalProps({confirmLoading: true});
            if(isUpdate.value){
                await updateCheckRule(formData)
            }else{
                await saveCheckRule(formData);
            }
            //关闭弹窗
            closeModal();
            //刷新列表
            emit('success');
        } finally {
            setModalProps({confirmLoading: false});
        }
    }

    /**
     * 校验
     * @param cellValue
     * @param callback
     */
    const validatePatternHandler = ({ cellValue }, callback) => {
        try {
            new RegExp(cellValue)
            callback(true)
        } catch (e) {
            callback(false, '请输入正确的正则表达式')
        }
    };

    const columns1 = ref<JVxeColumn[]>([
        {
            title: '位数',
            key: 'digits',
            type: JVxeTypes.inputNumber,
            minWidth: 180,
            validateRules: [
                { required: true, message: '${title}不能为空' },
                { pattern: /^[1-9]\d*$/, message: '请输入零以上的正整数' },
            ]
        },
        {
            title: '规则（正则表达式）',
            key: 'pattern',
            minWidth: 320,
            type: JVxeTypes.input,
            validateRules: [
                { required: true, message: '规则不能为空' },
                { handler: validatePatternHandler }
            ]
        },
        {
            title: '提示文本',
            key: 'message',
            minWidth: 180,
            type: JVxeTypes.input,
            validateRules: [
                { required: true, message: '${title}不能为空' },
            ]
        }
    ])

    const columns2 = ref<JVxeColumn[]>([
        {
            title: '优先级',
            key: 'priority',
            type: JVxeTypes.select,
            defaultValue: '1',
            options: [
                { title: '优先运行', value: '1' },
                { title: '最后运行', value: '0' },
            ],
            validateRules: []
        },
        {
            title: '规则（正则表达式）',
            key: 'pattern',
            width: '40%',
            type:  JVxeTypes.input,
            validateRules: [
                { required: true, message: '规则不能为空' },
                { handler: validatePatternHandler }
            ]
        },
        {
            title: '提示文本',
            key: 'message',
            width: '20%',
            type:  JVxeTypes.input,
            validateRules: [
                { required: true, message: '${title}不能为空' },
            ]
        },

    ])

</script>

